//package model.trader.portfolio;
//
//import model.market.BankOfCredit;
//import model.market.MarketInformation;
//import model.market.MarketManager;
//import model.market.Position;
//import model.trader.TradeInstruction;
//
///**
// * A standard portfolio strategy will hold only cash if the investor hates all assets. 
// * If the investor loves all assets then she will hold no cash. 
// * The values in between are more complicated..
// * 
// * Each asset preference is converted to a number from 0 to 20 (i.e. values are shifted up by 10)
// * then the asset preferences are squared.
// * 
// * The pot: The fraction of available capital allocated to assets is given by ln(sum of squaredpreferences)/ln(maximum sumpreference score)
// * 
// * The fraction of the pot that will be invested in a particular asset is given by the squared value over the sum of squared values.
// *  
// * @author andy
// *
// */
////AMXX: rename.
////AMXX: when deciding on best portfolio, consider the cost after expected market impact.
////AMXX: introduce aggression??
//public class StandardPortfolioStrategy implements PortfolioManagementStrategy{
//
//	LiquidityMeasure liquid = new LiquidityMeasure();
//	BankOfCredit bank = new BankOfCredit();
//	
//	public TradeInstruction[] allocate(Position pos, MarketManager market,
//			double[] analystPrices,
//			MarketInformation marketInfo) {
//		
//		double[] traderPreferences = new double[analystPrices.length];
//		for(int i=0;i<analystPrices.length;i++){
//			double marketPrice = market.getMarketPrice(i);
//			double fairPrice =analystPrices[i];
//			double preference= ((fairPrice-marketPrice)*15)/(fairPrice>marketPrice?fairPrice:marketPrice);
//			traderPreferences[i]=preference+10;
//		}
//	
//		double[] squares=new double[traderPreferences.length];
//		double squareSum=0;
//		double marketPriceSum= 0;
//		double prefSum=0;
//		for(int i=0;i<traderPreferences.length;i++){
//			
//			double square = traderPreferences[i]*traderPreferences[i];
//			squares[i]=square;
//			squareSum+=square;
//			marketPriceSum+=market.getMarketPrice(i);
//			prefSum+=traderPreferences[i];
//		}
//		double marketPriceAverage = marketPriceSum/market.getMarketPrices().length;
//		
//		double maxScore = 20*20*traderPreferences.length;
//		
//		//AMXX: this can end up negative..
//		double potSize = Math.log(squareSum)/Math.log(maxScore);
//		
//		//AMXX: somethings up with margin calls getting hit all the time.
//		double potValue = potSize*bank.getPossibleLongPosition(market.getMarketPrices(), pos, .2);
//		if(potValue<0){
//			System.out.println("Bank.. "+bank.getPossibleLongPosition(market.getMarketPrices(), pos, .2));
//			System.out.println("Pot. "+potSize);
//		}
//		System.out.println("\n\n--------------------Pot value: "+potValue+"----------"+pos.getWorth(market.getMarketPrices()));
//		TradeInstruction trades[] = new TradeInstruction[marketInfo.getNumberOfAssets()];
//		for(int assetReference=0;assetReference<traderPreferences.length;assetReference++){
//			double currentHolding=market.getMarketPrice(assetReference)*pos.getExecutedQuantity(assetReference);
//			//AMXX: market cap adjustment needs explaining/improving..
//			//AMXX: market cap adjustment is wrong anyway, because it doesn't balance out.. need something more sophisticated.
//			double desiredHolding=//squares[assetReference]/squareSum*potValue*(market.getMarketPrice(assetReference)/marketPriceAverage);
//				traderPreferences[assetReference]/prefSum*potValue*(market.getMarketPrice(assetReference)/marketPriceAverage);//AMXX: temp linear..
//			
//			TradeInstruction trade = new TradeInstruction();
//			trade.setAsset(assetReference);
//			trade.setNumberToTrade((int)((desiredHolding-currentHolding)/market.getMarketPrice(assetReference)));
//			trades[assetReference]=trade;
//			System.out.println("I want: "+trade.getNumberToTrade()+", I have: "+pos.getExecutedQuantity(assetReference));
//			
//		}
//
//		//AM: now we work out the hold prices...
//		double[] realMarketPrices = market.getMarketPrices();
//		for(int assetReference=0;assetReference<realMarketPrices.length;assetReference++){
//			double[] marketClone = new double[realMarketPrices.length];
//			System.arraycopy(realMarketPrices, 0, marketClone, 0, realMarketPrices.length);
//			int desiredTradeQuantity = trades[assetReference].getNumberToTrade();
//			
//			if(trades[assetReference].getNumberToTrade()>0){
//				double holdPrice = marketClone[assetReference]*1.01;
//				do{
//					
//					marketClone[assetReference]=holdPrice;
//					desiredTradeQuantity = getDesiredTradeQuantity(pos, assetReference, analystPrices, marketClone);
//					holdPrice*=1.01;
//				}while(desiredTradeQuantity>0);
//				
//			}else{
//				//AM: same same but different..
//				double holdPrice = marketClone[assetReference]/1.01;
//				do{
//					
//					marketClone[assetReference]=holdPrice;
//					desiredTradeQuantity = getDesiredTradeQuantity(pos, assetReference, analystPrices, marketClone);
//					trades[assetReference].addIndication(holdPrice, desiredTradeQuantity);
//					holdPrice/=1.01;
//				}while(desiredTradeQuantity<0);
//				
//			}
//			System.out.println("Asset:"+assetReference+" analyst: "+analystPrices[assetReference]+" market "+realMarketPrices[assetReference]+
//					" desired: "+trades[assetReference].getNumberToTrade()+" hold price: ");
//		}
//		
//		return trades;
//	}
//	
//	/**
//	 * 
//	 * @param pos
//	 * @param assetRef
//	 * @param market
//	 * @param analystPrices
//	 * @param marketPrices
//	 * @param marketInfo
//	 * @return the number of assets that the trader wants to buy or sell of the given asset at the given market price.
//	 */
//	private int getDesiredTradeQuantity(Position pos, int assetReference,
//												double[] analystPrices,double[] marketPrices) {
//		
//		//AMXX: a lot of copy paste code needs refactoring.
//		double[] traderPreferences = new double[analystPrices.length];
//		for(int i=0;i<analystPrices.length;i++){
//			double marketPrice = marketPrices[i];
//			double fairPrice =analystPrices[i];
//			double preference= ((fairPrice-marketPrice)*15)/(fairPrice>marketPrice?fairPrice:marketPrice);
//			traderPreferences[i]=preference+10;
//		}
//	
//		double[] squares=new double[traderPreferences.length];
//		double squareSum=0;
//		double marketPriceSum= 0;
//		double prefSum=0;
//		for(int i=0;i<traderPreferences.length;i++){
//			
//			double square = traderPreferences[i]*traderPreferences[i];
//			squares[i]=square;
//			squareSum+=square;
//			marketPriceSum+=marketPrices[i];
//			prefSum+=traderPreferences[i];
//		}
//		double marketPriceAverage = marketPriceSum/marketPrices.length;
//		
//		double maxScore = 20*20*traderPreferences.length;
//		
//		
//		double potSize = Math.log(squareSum)/Math.log(maxScore);
//		
//		//AMXX: somethings up with margin calls getting hit all the time.
//		double potValue = potSize*bank.getPossibleLongPosition(marketPrices, pos, .2);
//		
//		
//		double currentHolding=marketPrices[assetReference]*pos.getExecutedQuantity(assetReference);
//		//AMXX: market cap adjustment needs explaining/improving..
//		//AMXX: market cap adjustment is wrong anyway, because it doesn't balance out.. need something more sophisticated.
//		double desiredHolding=//squares[assetReference]/squareSum*potValue*(marketPrices[assetReference]/marketPriceAverage);
//			traderPreferences[assetReference]/prefSum*potValue*(marketPrices[assetReference]/marketPriceAverage);//AMXX: temp linear..
//		
//		return (int)((desiredHolding-currentHolding)/marketPrices[assetReference]);
//		
//	}
//
//}
